﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;

namespace Smart.Web.Mobile
{
    /// <summary>
    /// 
    /// </summary>
    public class MobileSettings
    {
        private static readonly MobileSettings instance = new MobileSettings();

        /// <summary>
        /// 
        /// </summary>
        public static MobileSettings Default
        {
            get { return instance; }
        }

        /// <summary>
        /// 
        /// </summary>
        public List<CarrierMatchingRule> MatchingRules { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public Dictionary<Carrier, CarrierSettings> CarrierSettings { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"></param>
        public void Init(string filename)
        {
            // 初期化
            MatchingRules = new List<CarrierMatchingRule>();

            CarrierSettings = new Dictionary<Carrier, CarrierSettings>();
            foreach( Carrier carrier in Enum.GetValues( typeof( Carrier ) ) )
            {
                CarrierSettings[ carrier ] = new CarrierSettings( carrier );
            }
            
            XmlDocument doc = new XmlDocument();
            doc.Load( filename );

            // rule
            foreach( XmlNode node in doc.SelectNodes( "/mobile/rules/rule" ) )
            {
                XmlAttribute carrierAttribute = node.Attributes[ "carrier" ];
                XmlAttribute containsAttribute = node.Attributes[ "contains" ];

                if( carrierAttribute != null )
                {
                    Carrier carrier = (Carrier)Enum.Parse( typeof(Carrier), carrierAttribute.Value, true );
                    MatchingRules.Add( new CarrierMatchingRule()
                    {
                        Carrier = carrier,
                        Contains = containsAttribute.Value,
                    } );
                }
            }

            // provider
            List<XmlDocument> providers = new List<XmlDocument>();
            List<Carrier> carriers = new List<Carrier>();
            foreach( XmlNode node in doc.SelectNodes( "/mobile/carriers/include" ) )
            {
                XmlAttribute fileAttribute = node.Attributes[ "file" ];

                XmlDocument docProvider = new XmlDocument();
                docProvider.Load( Path.Combine( Path.GetDirectoryName( filename ), fileAttribute.Value ) );

                XmlNode carrierNode = docProvider.SelectSingleNode( "/carrier" );
                if( carrierNode == null )
                {
                    continue;
                }
                XmlAttribute carrierNameAttribute = carrierNode.Attributes[ "name" ];
                if( carrierNameAttribute == null )
                {
                    continue;
                }
                Carrier carrier = (Carrier)Enum.Parse( typeof(Carrier), carrierNameAttribute.Value, true );

                providers.Add( docProvider );
                carriers.Add( carrier );
            }

            for( int i = 0; i < providers.Count(); i++ )
            {
                LoadProvider( providers[ i ], carriers[ i ] );
            }

            for( int i = 0; i < providers.Count(); i++ )
            {
                LoadProviderConvert( providers[ i ], carriers[ i ] );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="carrier"></param>
        private void LoadProvider(XmlDocument doc, Carrier carrier)
        {
            // pictgram
            foreach( XmlNode node in doc.SelectNodes( "/carrier/pictgrams/pictgram" ) )
            {
                XmlAttribute noAttribute = node.Attributes[ "no" ];
                XmlAttribute sjisAttribute = node.Attributes[ "sjis" ];
                XmlAttribute unicodeAttribute = node.Attributes[ "unicode" ];
                XmlAttribute nameAttribute = node.Attributes[ "name" ];

                if( ( noAttribute != null ) && ( unicodeAttribute != null ) )
                {
                    CarrierSettings[ carrier ].AddPictgram( new Pictgram()
                    {
                        No = Convert.ToInt32( noAttribute.Value ),
                        Sjis = ( sjisAttribute == null ? null : MobileUtil.HexToBytes( sjisAttribute.Value ) ),
                        Unicode = MobileUtil.HexToUnicode( unicodeAttribute.Value ),
                        Name = nameAttribute.Value,
                    } );
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="carrier"></param>
        private void LoadProviderConvert(XmlDocument doc, Carrier carrier)
        {
            // convert
            foreach( XmlNode node in doc.SelectNodes( "/carrier/converts/convert" ) )
            {
                XmlAttribute noAttribute = node.Attributes[ "no" ];

                foreach( XmlAttribute attribute in node.Attributes )
                {
                    if( attribute.Name.ToLower() != "no" )
                    {
                        Carrier toCarrier = (Carrier)Enum.Parse( typeof(Carrier), attribute.Name, true );

                        List<char> list = new List<char>();
                        foreach( string value in attribute.Value.Split( ',' ) )
                        {
                            int toNo;
                            if( Int32.TryParse( value, out toNo ) )
                            {
                                list.Add( CarrierSettings[ toCarrier ].GetPictgramByNo( toNo ).Unicode );
                            }
                            else
                            {
                                list.AddRange( value.ToCharArray() );
                            }
                        }

                        char src = CarrierSettings[ carrier ].GetPictgramByNo( Convert.ToInt32( noAttribute.Value ) ).Unicode;

                        CarrierSettings[ toCarrier ].AddConvert( src, list.ToArray() );
                    }
                }
            }
        }
    }
}
